Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ftdi led device #521

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft

Ftdi led device #521

wants to merge 7 commits into from

Conversation

nurikk
Copy link
Contributor

@nurikk nurikk commented Feb 25, 2023

Hello! This PR introduces ftdilib1 led device implementation. FTDI chips are common usb2serial/spi/whatever chips, and are available for 5-10$ from Chinese website as various breakout boards.

Screenshot 2023-02-25 at 21 52 19

My wiring is following:

FTDI  |  APA102 
AD0 -> CLOCK
AD1 -> DATA

AD3 -> CS (active low) // can be used to drive logic shifter OE pins

FTDI  |  WS2812 or SK6812
AD1 -> DATA

AD3 -> CS (active low) // can be used to drive logic shifter OE pins

Current implementation will try to use any (first) fetid chip it discovers in system.
I've tested my code on MacOS and webos7(lg tv c2), no extra drivers required.

This implementation is tested against APA102, WS1218 and SK6812.
There are two channel chips like FT2232HQ which can drive more that one led segments.

I built webos-hyperhdr-loader with latest buildroot and have following debug build for testing for webos users

Latest build attracts can be found here

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Docs
  • Build-related changes
  • Other, please describe:

If changing the UI of web configuration, please provide the before/after screenshot:

Does this PR introduce a breaking change? (check one)

  • Yes
  • No

Furutre improvements:

  • Allow pick specific ftdi device (in case if you have multiple ftdi chips connected)
  • Stretch task, in another PR: Multisegment support

PS: This PR doesn't require to be merged straight away, let's test it for some time

@awawa-dev
Copy link
Owner

awawa-dev commented Feb 26, 2023

Hi
Thank you for the new LED driver :) Looks good to me and can be merged. Just one suggestion: modifying that single line in LedDevice.cpp won't change anything about ftdi support, so I'd rather put it off until the next iteration of refactoring this key component if it is not necessary and is not related to the new feature.

Have you tried bit banging to control the Neopixel LEDs? In theory at least 4*800kHz clock would be needed and then:
coding 0 bit => one high, three lows
coding 1 bit => three high, one low
and then reset pulse at the end: low signal for 80(sk6812)-300(ws2812b)us. But this is just a theory, in practice the result depends on how stable the timings will be provided by the device.

@nurikk nurikk marked this pull request as draft February 26, 2023 14:33
@nurikk nurikk marked this pull request as ready for review February 26, 2023 23:52
@nurikk
Copy link
Contributor Author

nurikk commented Feb 26, 2023

Hi Thank you for the new LED driver :) Looks good to me and can be merged. Just one suggestion: modifying that single line in LedDevice.cpp won't change anything about ftdi support, so I'd rather put it off until the next iteration of refactoring this key component if it is not necessary and is not related to the new feature.

Have you tried bit banging to control the Neopixel LEDs? In theory at least 4*800kHz clock would be needed and then: coding 0 bit => one high, three lows coding 1 bit => three high, one low and then reset pulse at the end: low signal for 80(sk6812)-300(ws2812b)us. But this is just a theory, in practice the result depends on how stable the timings will be provided by the device.

yep, I had similar idea about neopixel implementation, shouldn't be quite complicated. I'll try to implement, maybe will find someone who's willing to test it :) Btw I've removed change in LedDevice and overloaded start method in ProviderFtdi instead :) I still don't get that close in start logic

@nurikk nurikk marked this pull request as draft March 5, 2023 20:44
@nurikk nurikk force-pushed the ftdi branch 2 times, most recently from ccd1f4a to 5fc191e Compare March 5, 2023 21:05
@nurikk nurikk marked this pull request as ready for review March 5, 2023 21:23
@nurikk nurikk force-pushed the ftdi branch 3 times, most recently from f8affa8 to 57480ed Compare March 7, 2023 19:29
@nurikk
Copy link
Contributor Author

nurikk commented Mar 7, 2023

Hi @awawa-dev, I've implemented ws2812 support

@awawa-dev
Copy link
Owner

awawa-dev commented Mar 8, 2023

Great 👍 Did you test it on larger LED strips? Similar sk6812 SPI driver doesn't work for my LED strip that's why I suggested approach that is used e.g. by Neopixelbus library (fixed not adjustable clock that is set to multiply of Neopixel frequency, a bit different bit encoding) but not sure if it was caused by the Rpi SPI limitation/configuration.

@nurikk-sa
Copy link
Contributor

I'd love to test on larger led strips, but my ws2812 test setup is made of a single led, there's not much I can do about it.

@satgit62
Copy link

satgit62 commented Mar 15, 2023

Ambilight FT232H implementation.
Hello,
I've been following this project by @nurikk on Discord from the beginning, and I was glad someone came up with such a brilliant idea. I have therefore made myself smart, and I was firmly convinced that a lot of potential in such a FTDI developer board. I ordered the board at Amazon “FT232H USB-to-JTAG-UART/FIFO-SPI / I2C-Module, multifunction module with three pin headers”. Since @nurikk had only Apa102 integrated, I asked whether this would also be possible for SK6812RGBW. The implementation followed promptly and could do a whole series of test.
The board was immediately recognized by my LG webOS 3.9 as FTDI USB Serial Device. With the new HyperHDR loader build from @nurikk, I could start right away. Under controller type Sk68_12ftdi, set RGB byte to GRB and baud rate to 3200000. Since the color calibration of WLED was not implemented at the beginning, I tested a lot and the best results were under “Subtract minimum, custom” with R120, G100 and B160. You can adjust quite a lot, so everyone can make his individual adjustment. The only drawback was the brightness level.
There was no option to reduce it anywhere. The whole thing outshines and overdrives everything.
After consultation with @nurikk, the “White balance correction” from WLED was installed, which allows the use of the dual function (RGB+W) of the SK6812RGBW, as well as brightness delimitation function. The function for Dual is called “Wled auto”.
Moreover, you can still make color corrections in HyperHDR itself until the desired result is achieved.
These new WLED implementations have helped to ensure that nothing more stands in the way and the project FTDI Ambilight a real alternative to WLED due to the simple wiring and direct USB control. Clearly everyone must decide for themselves, but for those who do not have a good WLAN or LAN possibility, this is the better choice. This runs as fast and reliable as @awawa's HyperSerial. Great job by @nurikk, thanks for this.

FT232H
sk6812_ftdi1
sk6812_ftdi2
sk6812_ftdi3
sk6812_ftdi4
sk6812_ftdi5

@awawa-dev
Copy link
Owner

Hint: there is a white channel algorithm in HyperSerialEsp8266/ESP32/HyperSPI that in my opinion outperforms this algos from WLED and also allows custom settings. And it's also easy to implement.

@satgit62
Copy link

That would be fantastic, of course, if it's possible.

@satgit62
Copy link

Hi,
@nurikk, you did a great job again.
I just tested the new HyperHDR build, with “Hyperserial neutral white” color algorithm at a brightness limit of 120 from 255, HDR global off, and it works as it should. I made a small video for comparison with the “Wled auto” algorithm. Personally think that “Wled auto algorithm” brings more vivid colors and “Hyperserial neutral white” color algorithm has finer gradation. Either way, there is the right setting for everyone to choose from. But this is just my visual impression.

sk6812_ftdi_Wled auto

sk6812_ftdi_Wled1.auto.mp4

sk6812ftdi_Hyperserial neutral white

sk6812ftdi_Hyperserial.neutral.white1.mp4

@awawa-dev
Copy link
Owner

I'm hoping to get the FT232H (BTW and 100M logic analyzer and oscilloscope) next month so I can test it out.

@nurikk
Copy link
Contributor Author

nurikk commented Mar 22, 2023

I'm hoping to get the FT232H (BTW and 100M logic analyzer and oscilloscope) next month so I can test it out.

Haha, someone broke the piggy bank 😀 congratulations on getting new hardware! 🤩

@satgit62
Copy link

I'm hoping to get the FT232H (BTW and 100M logic analyzer and oscilloscope) next month so I can test it out.

Hello, I hope that someday, when you have tested everything, you will integrate the FTDI implementation of @nurikk in your release version.

@awawa-dev
Copy link
Owner

Still I prefer using auto discovery when it handles almost 100% cases without forcing user to specify a unnecessary path. It's different situation than e.g. configuring path for SPI devices which provide no feedback if the device is present at the path or not which may mislead auto-discovery, ftdi reports only valid device. Please revert that commit.

@satgit62
Copy link

Hello, is there any chance to implement the Hyperion FTDI for Windows?

@awawa-dev
Copy link
Owner

Yes, I fixed the windows build. It detects devices and tries to open in "auto" mode (selecting a specific device didn't work before). But there are two main problems: libusb has nasty requirements when it comes to accessing physical devices on Windows (non-root users have a similar problem on Linux, but at least there is a workaround for that OS) and brew doesn't provide backwards compatible libftdi /libusb libraries for 10.15. And many Apple devices continued to use this version of macOS without being able to upgrade to 12.x.

@satgit62
Copy link

Hello, @awawa-dev and @Nurrik
Thanks for the implementation of the FTDI Board in HyperHDR for different platforms. Would be very happy who this is implemented for Windows and would like to test on a Windows PC. This is very interesting for most PCs gaming gamers who would get a good cheap hardware without many bells and whistles for LEDs. I already have WLED/ESP running with Hyperion Screen Capture along with HyperHDR successfully tested on Windows PC.

@awawa-dev
Copy link
Owner

awawa-dev commented May 10, 2023

Hi @nurikk
Finally I got the necessary equipment and found a moment of free time to test. Since libusb on Windows requires the installation of a customized libusbk driver, I ran tests on Linux based on your version before my commit. It didn't work for the pi user, I didn't want to fiddle with udev rules so unfortunately I had to switch the service to root. To begin with sk6812 RGBW:
obraz

The frequency is a bit too high from the ideal 800KHz, but the timing are the most correct for sk6812 RGBW.

Then ws2812b:
obraz

It's worse here. The frequency is also a bit too high, but it's not a problem. ws2812b has been featured in several revisions over time, the recommended timings have changed but the only critical change was the increase in reset time from 50us to about 280-300us in the latest revisions which broke some ws2812b support libraries at the time. The pulse timing of the bit was backwards compatible regardless of what the manufacturer recommended in the documentation. For ws2812b, practical tests showed that high-time of encoded 1 should be at least 625ns(source), while here we have timings 610ns identical to sk6812b, which will most likely end up with problems (flickering) for ws2812b depending on their version.

Do you know if libftdi was replaced with a proprietary API from the FTDI manufacturer, wouldn't that solve the permissions issues on all systems? The ftdi library doesn't need to be distributed or included in the build if it will be loaded dynamically: a header file is enough.

@awawa-dev awawa-dev marked this pull request as draft July 14, 2023 19:38
@j-st1
Copy link

j-st1 commented Oct 10, 2023

Hi there! I'd love to try this out. Is it going to work with ws2801? I have one spare lying around..

@satgit62
Copy link

Hi there! I'd love to try this out. Is it going to work with ws2801? I have one spare lying around..

Since the WS2801 LED is an SPI 3 channel IC with 2.5kHz and has different parameters than the Apa102 and WS2812 Neo-Pixel and the SK6812 RGBW 5050 IC respectively, which have completely different clock frequencies, will not work here. It is necessary that @nurikk also integrates the WS2801 in drivers.

@j-st1
Copy link

j-st1 commented Oct 15, 2023

Too bad :(. Thanks for the detailed answer!

@satgit62
Copy link

satgit62 commented Jan 2, 2024

@nurikk

Hi,
The Hyperion loader brings HyperHDR version 20.0.0.0beta1 to our LG. Unfortunately, your FTDI implementation is not included.
Is it possible to publish the FTDI in the new version?

@nurikk
Copy link
Contributor Author

nurikk commented Feb 25, 2024

@nurikk

Hi, The Hyperion loader brings HyperHDR version 20.0.0.0beta1 to our LG. Unfortunately, your FTDI implementation is not included. Is it possible to publish the FTDI in the new version?

hey @satgit62 I just build latest version https://github.com/nurikk/hyperhdr-webos-loader/actions/runs/8036974919

@satgit62
Copy link

satgit62 commented Feb 25, 2024

@nurikk
Hi, The Hyperion loader brings HyperHDR version 20.0.0.0beta1 to our LG. Unfortunately, your FTDI implementation is not included. Is it possible to publish the FTDI in the new version?
hey @satgit62 I just build latest version https://github.com/nurikk/hyperhdr-webos-loader/actions/runs/8036974919

Thank you very much, @nurikk, I've managed that too. I'm already looking forward to the further development.

@satgit62
Copy link

satgit62 commented Feb 25, 2024

@nurikk
Hi,
Do you know why on my self compiled version of your FTDI-branch I have to type in terminal ln -s /lib/libudev.so.0.13.1 /media/developer/apps/usr/palm/services/org.webosbrew.hyperhdr.loader.service/hyperhdr/libudev.so.1 to start HyperHDR daemon?
Is a reference/symlink to the libudev not made automatically?
EDIT: even with your version, I have to execute the command in Terminal. (webOS 3.9.2) If I install the regular version via Homebrew Channel, I don't have to do this.

@throwaway96
Copy link

@satgit62

Do you know why on my self compiled version of your FTDI-branch I have to type in terminal ln -s /lib/libudev.so.0.13.1 /media/developer/apps/usr/palm/services/org.webosbrew.hyperhdr.loader.service/hyperhdr/libudev.so.1 to start HyperHDR daemon?

It's because (e)udev was ~recently enabled in the default buildroot-nc4 config (openlgtv/buildroot-nc4@5696b70), and things that link against our libudev get a reference to libudev.so.1. Before eudev was enabled, packages would detect that libudev was unavailable, disable the code that depends on it, and not try to link against it.

We can't just switch to an older eudev with libudev.so.0, since webOS 4.0+ has libudev.so.1. There are various workarounds though: for example, you can build br-nc4 with eudev disabled. You could also try deleting arm-webos-linux-gnueabi/sysroot/usr/lib/pkgconfig/libudev.pc etc.

This doesn't affect the build on Homebrew Channel because it's built using the hyperhdr-webos-loader build workflow, which uses a br-nc4 version from 2022 (before eudev was enabled).

@satgit62
Copy link

satgit62 commented Mar 28, 2024

@satgit62

Do you know why on my self compiled version of your FTDI-branch I have to type in terminal ln -s /lib/libudev.so.0.13.1 /media/developer/apps/usr/palm/services/org.webosbrew.hyperhdr.loader.service/hyperhdr/libudev.so.1 to start HyperHDR daemon?

It's because (e)udev was ~recently enabled in the default buildroot-nc4 config (openlgtv/buildroot-nc4@5696b70), and things that link against our libudev get a reference to libudev.so.1. Before eudev was enabled, packages would detect that libudev was unavailable, disable the code that depends on it, and not try to link against it.

We can't just switch to an older eudev with libudev.so.0, since webOS 4.0+ has libudev.so.1. There are various workarounds though: for example, you can build br-nc4 with eudev disabled. You could also try deleting arm-webos-linux-gnueabi/sysroot/usr/lib/pkgconfig/libudev.pc etc.

This doesn't affect the build on Homebrew Channel because it's built using the hyperhdr-webos-loader build workflow, which uses a br-nc4 version from 2022 (before eudev was enabled).

@throwaway96 Hi, thanks for the explanation, so I will delete the libudev.pc from arm-webos-linux-gnueabi/sysroot/usr/lib/pkgconfig/ and see if the daemon starts then.

@satgit62
Copy link

@nurikk
Hi, The Hyperion loader brings HyperHDR version 20.0.0.0beta1 to our LG. Unfortunately, your FTDI implementation is not included. Is it possible to publish the FTDI in the new version?

hey @satgit62 I just build latest version https://github.com/nurikk/hyperhdr-webos-loader/actions/runs/8036974919

Hi @nurikk,
Since HyperHDR is reaching the stable stage and v20.0.0.0 is running very well, I ask if you would also include this in your repository for FTDI. The latest 20.0.0.0beta2 is still working fine, but it would be nice if FTDI users can also enjoy the new version.

@awawa-dev
Copy link
Owner

Since the LED driver model will soon be significantly simplified in HyperHDR, I can add these changes and make the appropriate modifications myself. At least when it comes to SPI. In the case of Neopixel, I still have doubts about timings.

BTW, in general, the approach to emulating Neopixel using devices designed for protocol SPI is wrong or at least prone to various vulnerabilities. Therefore it doesn't work well eg. when using SPI in RPi for Neopixel LEDs. The source is the nature of SPI and the many variants of the protocol. Let me give you the simplest example.
Here the emulation works correctly:
SPI is OK (3 bit 110)
Neopixel is OK (pulse length on the upper data axis let's say x ns)

obraz

And here the emulation does not work OK, but SPI is still within the limits allowed by the protocol. This may occur, for example, in the event of emitter overload or its buffer underrun. It may just disable the SPI clock for a while until the data is ready.
SPI is still OK (3 bit 110)
Neopixel is not OK (pulse length on the upper data axis could be even n * x ns)

obraz

@satgit62
Copy link

satgit62 commented Jun 28, 2024

Since the LED driver model will soon be significantly simplified in HyperHDR, I can add these changes and make the appropriate modifications myself. At least when it comes to SPI. In the case of Neopixel, I still have doubts about timings.

BTW, in general, the approach to emulating Neopixel using devices designed for protocol SPI is wrong or at least prone to various vulnerabilities. Therefore it doesn't work well eg. when using SPI in RPi for Neopixel LEDs. The source is the nature of SPI and the many variants of the protocol. Let me give you the simplest example. Here the emulation works correctly: SPI is OK (3 bit 110) Neopixel is OK (pulse length on the upper data axis let's say x ns)

obraz

And here the emulation does not work OK, but SPI is still within the limits allowed by the protocol. This may occur, for example, in the event of emitter overload or its buffer underrun. It may just disable the SPI clock for a while until the data is ready. SPI is still OK (3 bit 110) Neopixel is not OK (pulse length on the upper data axis could be even n * x ns)

obraz

Yes, you are right, that is a good argument. I also belong to the faction that looks for perfection. The HyperSerialPico, like the HyperSerial, plays in the first league, but there are still people who are not looking for perfection, but for very simple solutions. In this case, FTDI comes first because of its handling under webOS. Those who use FTDI devices are happy to accept that not everything works perfectly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants